#include "Formatter.h"

void mylog::TimeFormatItem::Format(std::ostream& out,
                                   const LogMessage& msg){
    std::time_t time = std::chrono::system_clock::to_time_t(msg.m_ctime);
    std::tm tm;
    localtime_r(&time, &tm);
    std::stringstream ss;
    ss << std::put_time(&tm, _time_fmt.c_str());
    out << ss.str();
}

void mylog::Formatter::Format(std::ostream& out, const LogMessage& msg) {
    for (auto& it : _items)
        it->Format(out, msg);
}

std::string mylog::Formatter::Format(const LogMessage& msg) {
    std::stringstream ssm;
	Format(ssm, msg);
	return ssm.str();
}

// "[%d{%H:%M:%S}][%p][%c][%t][%f:%l]%T%m%n"
bool mylog::Formatter::ParsePattern() {
    std::unordered_set<char> fmt_set = {'d', 'p', 'c', 't', 'f',
                                        'l', 'm', 'T', 'n'};
    std::vector<std::pair<std::string, std::string>> fmt_order;
    std::string key, val;
    size_t pos = 0;
    while (pos < _pattern.size()) {
        // 1. 先处理原始字符串，格式化字符都是以%开头的
        if (_pattern[pos] != '%') {
            val.push_back(_pattern[pos++]); // val = [
            continue;
        }

        // 1.2 对%%进行处理转义,(走到这里当前位置一定等于%)
        if (pos + 1 < _pattern.size() && _pattern[pos + 1] == '%') {
            val.push_back('%');
            pos += 2;
            continue;
        }

        // 1.3 将组织好原始字符串放入fmt_order中
        if (!val.empty()) {
            fmt_order.emplace_back(std::make_pair("", val)); // "": [
            val.clear();       // val=[]
        }

        // 2 处理格式化字符
		// 2.1 走到这里说明当前位置是%,下一个字符可能是格式化字符
        if (pos + 1 >= _pattern.size()) {
            std::cerr << "% 后无格式化字符！" << std::endl;
            return false;
        }

        auto it = fmt_set.find(_pattern[pos + 1]);
        if (it == fmt_set.end()) {
            std::cerr << "格式化字符不正确" << std::endl;
            return false;
        }
        key.push_back(_pattern[pos + 1]);
        pos += 2;
        
        // 3.处理%d的格式化子串 如{%H:%M:%S}
        if (pos < _pattern.size() && _pattern[pos] == '{') {
            size_t end_pos = _pattern.find_first_of('}', pos + 1);
            if (end_pos == std::string::npos) {
                std::cerr << "格式化子串{}匹配出现问题" << std::endl;
                return false;
            }
            val += _pattern.substr(pos + 1, end_pos - pos - 1);
            pos = end_pos + 1;
        }
        fmt_order.emplace_back(std::make_pair(key, val));
        key.clear();
        val.clear();
    }
    for (auto& it : fmt_order)_items.push_back(CreateItem(it.first, it.second));
    

    return true;
}
mylog::FormatItem::ptr mylog::Formatter::CreateItem(const std::string& key,
                                                    const std::string& val) {
    // 构造日期格式化子项
    if (key == "d")
        return std::make_shared<TimeFormatItem>(val);
    // 构造日志级别格式化子项
    if (key == "p")
        return std::make_shared<LevelFormatItem>();
    // 构造日志器名称格式化子项
    if (key == "c")
        return std::make_shared<LoggerFormatItem>();
    // 构造线程id格式化子项
    if (key == "t")
        return std::make_shared<ThreadFormatItem>();
    // 构造文件名格式化子项
    if (key == "f")
        return std::make_shared<FileFormatItem>();
    // 构造行号格式化子项
    if (key == "l")
        return std::make_shared<LineFormatItem>();
    // 构造日志消息格式化子项
    if (key == "m")
        return std::make_shared<MsgFormatItem>();
    // 构造缩进格式化子项
    if (key == "T")
        return std::make_shared<TabFormatItem>();
    // 构造换行格式化子项
    if (key == "n")
        return std::make_shared<NLineFormatItem>();
    // 没有匹配的格式化字符就构造 其他格式化子项
    return std::make_shared<OtherFormatItem>(val);
}

void testFormatter() {
    // 创建一个 LogMessage 对象
    mylog::LogMessage logMsg(mylog::LogLevel::Level::WARNING, "MyLogger", __FILE__,
                             __LINE__, "This is a log message");
    // 创建一个 Formatter 对象
    mylog::Formatter formatter("[%d{%Y-%m-%d %H:%M:%S}][%p][%c][%t][%f:%l]%T%m%n");
    // 将日志输出到标准输出流
    formatter.Format(std::cout, logMsg);
}